#include <MsTimer2.h>     //定时器库的头文件

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif


const unsigned char color_model1[768] =
{
    0xbf, 0x00, 0x00, 0xbf, 0x03, 0x00, 0xbf, 0x06, 0x00, 0xbf, 0x0c, 0x00, 0xbf, 0x0f, 0x00, 0xbf, 0x16, 0x00, 0xbf, 0x19, 0x00, 0xbf, 0x1c, 0x00, 0xbf, 0x23, 0x00, 0xbf, 0x26, 0x00, 0xbf, 0x2c, 0x00, 0xbf, 0x2f, 0x00, 0xbf, 0x33, 0x00, 0xbf, 0x39, 0x00, 0xbf, 0x3c, 0x00, 0xbf, 0x42, 0x00,
    0xbf, 0x46, 0x00, 0xbf, 0x49, 0x00, 0xbf, 0x4f, 0x00, 0xbf, 0x52, 0x00, 0xbf, 0x59, 0x00, 0xbf, 0x5c, 0x00, 0xbf, 0x5f, 0x00, 0xbf, 0x66, 0x00, 0xbf, 0x69, 0x00, 0xbf, 0x6f, 0x00, 0xbf, 0x72, 0x00, 0xbf, 0x75, 0x00, 0xbf, 0x7c, 0x00, 0xbf, 0x7f, 0x00, 0xbf, 0x85, 0x00, 0xbf, 0x89, 0x00,
    0xbf, 0x8f, 0x00, 0xbf, 0x92, 0x00, 0xbf, 0x95, 0x00, 0xbf, 0x9c, 0x00, 0xbf, 0x9f, 0x00, 0xbf, 0xa5, 0x00, 0xbf, 0xa8, 0x00, 0xbf, 0xac, 0x00, 0xbf, 0xb2, 0x00, 0xbf, 0xb5, 0x00, 0xbf, 0xbc, 0x00, 0xbf, 0xbf, 0x00, 0xbc, 0xbf, 0x00, 0xb5, 0xbf, 0x00, 0xb2, 0xbf, 0x00, 0xac, 0xbf, 0x00,
    0xa8, 0xbf, 0x00, 0xa5, 0xbf, 0x00, 0x9f, 0xbf, 0x00, 0x9c, 0xbf, 0x00, 0x95, 0xbf, 0x00, 0x92, 0xbf, 0x00, 0x8f, 0xbf, 0x00, 0x89, 0xbf, 0x00, 0x85, 0xbf, 0x00, 0x7f, 0xbf, 0x00, 0x7c, 0xbf, 0x00, 0x79, 0xbf, 0x00, 0x72, 0xbf, 0x00, 0x6f, 0xbf, 0x00, 0x69, 0xbf, 0x00, 0x66, 0xbf, 0x00,
    0x5f, 0xbf, 0x00, 0x5c, 0xbf, 0x00, 0x59, 0xbf, 0x00, 0x52, 0xbf, 0x00, 0x4f, 0xbf, 0x00, 0x49, 0xbf, 0x00, 0x46, 0xbf, 0x00, 0x42, 0xbf, 0x00, 0x3c, 0xbf, 0x00, 0x39, 0xbf, 0x00, 0x33, 0xbf, 0x00, 0x2f, 0xbf, 0x00, 0x2c, 0xbf, 0x00, 0x26, 0xbf, 0x00, 0x23, 0xbf, 0x00, 0x1c, 0xbf, 0x00,
    0x19, 0xbf, 0x00, 0x16, 0xbf, 0x00, 0x0f, 0xbf, 0x00, 0x0c, 0xbf, 0x00, 0x06, 0xbf, 0x00, 0x03, 0xbf, 0x00, 0x00, 0xbf, 0x00, 0x00, 0xbf, 0x06, 0x00, 0xbf, 0x09, 0x00, 0xbf, 0x0f, 0x00, 0xbf, 0x13, 0x00, 0xbf, 0x16, 0x00, 0xbf, 0x1c, 0x00, 0xbf, 0x1f, 0x00, 0xbf, 0x26, 0x00, 0xbf, 0x29,
    0x00, 0xbf, 0x2f, 0x00, 0xbf, 0x33, 0x00, 0xbf, 0x36, 0x00, 0xbf, 0x3c, 0x00, 0xbf, 0x3f, 0x00, 0xbf, 0x46, 0x00, 0xbf, 0x49, 0x00, 0xbf, 0x4c, 0x00, 0xbf, 0x52, 0x00, 0xbf, 0x56, 0x00, 0xbf, 0x5c, 0x00, 0xbf, 0x5f, 0x00, 0xbf, 0x62, 0x00, 0xbf, 0x69, 0x00, 0xbf, 0x6c, 0x00, 0xbf, 0x72,
    0x00, 0xbf, 0x75, 0x00, 0xbf, 0x79, 0x00, 0xbf, 0x7f, 0x00, 0xbf, 0x82, 0x00, 0xbf, 0x89, 0x00, 0xbf, 0x8c, 0x00, 0xbf, 0x8f, 0x00, 0xbf, 0x95, 0x00, 0xbf, 0x99, 0x00, 0xbf, 0x9f, 0x00, 0xbf, 0xa2, 0x00, 0xbf, 0xa5, 0x00, 0xbf, 0xac, 0x00, 0xbf, 0xaf, 0x00, 0xbf, 0xb5, 0x00, 0xbf, 0xb8,
    0x00, 0xbf, 0xbf, 0x00, 0xbc, 0xbf, 0x00, 0xb8, 0xbf, 0x00, 0xb2, 0xbf, 0x00, 0xaf, 0xbf, 0x00, 0xa8, 0xbf, 0x00, 0xa5, 0xbf, 0x00, 0xa2, 0xbf, 0x00, 0x9c, 0xbf, 0x00, 0x99, 0xbf, 0x00, 0x92, 0xbf, 0x00, 0x8f, 0xbf, 0x00, 0x8c, 0xbf, 0x00, 0x85, 0xbf, 0x00, 0x82, 0xbf, 0x00, 0x7c, 0xbf,
    0x00, 0x79, 0xbf, 0x00, 0x75, 0xbf, 0x00, 0x6f, 0xbf, 0x00, 0x6c, 0xbf, 0x00, 0x66, 0xbf, 0x00, 0x62, 0xbf, 0x00, 0x5f, 0xbf, 0x00, 0x59, 0xbf, 0x00, 0x56, 0xbf, 0x00, 0x4f, 0xbf, 0x00, 0x4c, 0xbf, 0x00, 0x49, 0xbf, 0x00, 0x42, 0xbf, 0x00, 0x3f, 0xbf, 0x00, 0x39, 0xbf, 0x00, 0x36, 0xbf,
    0x00, 0x2f, 0xbf, 0x00, 0x2c, 0xbf, 0x00, 0x29, 0xbf, 0x00, 0x23, 0xbf, 0x00, 0x1f, 0xbf, 0x00, 0x19, 0xbf, 0x00, 0x16, 0xbf, 0x00, 0x13, 0xbf, 0x00, 0x0c, 0xbf, 0x00, 0x09, 0xbf, 0x00, 0x03, 0xbf, 0x00, 0x00, 0xbf, 0x03, 0x00, 0xbf, 0x09, 0x00, 0xbf, 0x0c, 0x00, 0xbf, 0x13, 0x00, 0xbf,
    0x16, 0x00, 0xbf, 0x19, 0x00, 0xbf, 0x1f, 0x00, 0xbf, 0x23, 0x00, 0xbf, 0x29, 0x00, 0xbf, 0x2c, 0x00, 0xbf, 0x2f, 0x00, 0xbf, 0x36, 0x00, 0xbf, 0x39, 0x00, 0xbf, 0x3f, 0x00, 0xbf, 0x42, 0x00, 0xbf, 0x46, 0x00, 0xbf, 0x4c, 0x00, 0xbf, 0x4f, 0x00, 0xbf, 0x56, 0x00, 0xbf, 0x59, 0x00, 0xbf,
    0x5f, 0x00, 0xbf, 0x62, 0x00, 0xbf, 0x66, 0x00, 0xbf, 0x6c, 0x00, 0xbf, 0x6f, 0x00, 0xbf, 0x75, 0x00, 0xbf, 0x79, 0x00, 0xbf, 0x7c, 0x00, 0xbf, 0x82, 0x00, 0xbf, 0x85, 0x00, 0xbf, 0x8c, 0x00, 0xbf, 0x8f, 0x00, 0xbf, 0x92, 0x00, 0xbf, 0x99, 0x00, 0xbf, 0x9c, 0x00, 0xbf, 0xa2, 0x00, 0xbf,
    0xa5, 0x00, 0xbf, 0xa8, 0x00, 0xbf, 0xaf, 0x00, 0xbf, 0xb2, 0x00, 0xbf, 0xb8, 0x00, 0xbf, 0xbc, 0x00, 0xbf, 0xbf, 0x00, 0xbf, 0xbf, 0x00, 0xb8, 0xbf, 0x00, 0xb5, 0xbf, 0x00, 0xaf, 0xbf, 0x00, 0xac, 0xbf, 0x00, 0xa8, 0xbf, 0x00, 0xa2, 0xbf, 0x00, 0x9f, 0xbf, 0x00, 0x99, 0xbf, 0x00, 0x95,
    0xbf, 0x00, 0x8f, 0xbf, 0x00, 0x8c, 0xbf, 0x00, 0x89, 0xbf, 0x00, 0x82, 0xbf, 0x00, 0x7f, 0xbf, 0x00, 0x79, 0xbf, 0x00, 0x75, 0xbf, 0x00, 0x72, 0xbf, 0x00, 0x6c, 0xbf, 0x00, 0x69, 0xbf, 0x00, 0x62, 0xbf, 0x00, 0x5f, 0xbf, 0x00, 0x5c, 0xbf, 0x00, 0x56, 0xbf, 0x00, 0x52, 0xbf, 0x00, 0x4c,
    0xbf, 0x00, 0x49, 0xbf, 0x00, 0x46, 0xbf, 0x00, 0x3f, 0xbf, 0x00, 0x3c, 0xbf, 0x00, 0x36, 0xbf, 0x00, 0x33, 0xbf, 0x00, 0x2f, 0xbf, 0x00, 0x29, 0xbf, 0x00, 0x26, 0xbf, 0x00, 0x1f, 0xbf, 0x00, 0x1c, 0xbf, 0x00, 0x19, 0xbf, 0x00, 0x13, 0xbf, 0x00, 0x0f, 0xbf, 0x00, 0x09, 0xbf, 0x00, 0x06
};
   
#define LED_PIN   12    //定义LED点阵 IO
#define LED_COUNT 256   //定义LED数
#define KEY_1     2     //按钮1 - 模式切换按钮
#define KEY_2     3     //按钮2 - 模式下微调按钮
#define ADC_1     A7    //定义旋钮IO

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);  //全彩LED的型号和参数
int adc_current,adc_last = 0;   //ADC读取值
int keyModel = 0;                     //按键一切换的模式
int stepTime = 100;                  //驱动定时器 ms

void initSys();
int  iToLed(int i);
void HSVtoRGB(unsigned char *r, unsigned char *g, unsigned char *b, int h, int s, int v);

void showModel_close();
void showModel_0(); 
void showModel_1(int speed,bool vh);
void showModel_2(int speed); 
void showModel_3(); 
void showModel_4(); 

void key_1_interrupt();
void key_2_interrupt();
void ADC_1_onTimer();

void setup() 
{
  initSys();
}
void loop() 
{
  if(keyModel == 0) showModel_0();
  else if(keyModel == 1) showModel_1(16,0);
  else if(keyModel == 2) showModel_2(1);
  else if(keyModel == 3) showModel_3();
  else if(keyModel == 4) showModel_4();
  else showModel_close();
  delay(stepTime);
}                                

void initSys()
{
  //串口初始化
  Serial.begin(115200);
  Serial.print("start.......");
  
  //led点阵初始化
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif 

  //按键中断初始化
  attachInterrupt(0, key_1_interrupt, FALLING);  //下降沿触发，触发中断0，调用blink函数
  attachInterrupt(1, key_2_interrupt, FALLING);  //下降沿触发，触发中断0，调用blink函数
  
  strip.begin();           // 初始化对象    
  for(int ledPos = 0;ledPos < LED_COUNT;ledPos ++)
    strip.setPixelColor(ledPos, 255, 255, 255);    
  strip.setBrightness(0);
  strip.show();
  

  //初始化adc读取
  //pinMode(ADC_PIN,INPUT);
  MsTimer2::set(20, ADC_1_onTimer); //设置中断，每1000ms进入一次中断服务程序 onTimer()
  MsTimer2::start(); //开始计时_开启定时器中断
  
}

void key_1_interrupt()  //中断函数
{              
  keyModel ++;
  if(keyModel >= 3)
    keyModel = 0;
    
//  Serial.print("keyModel：");
//  Serial.println(keyModel);
}
void key_2_interrupt()  //中断函数
{          
  stepTime += 100;
  if(stepTime > 1000) stepTime = 100;     
//  Serial.print("keyModel：");
//  Serial.println(keyModel);
}
void ADC_1_onTimer()    //该定时器用于检测ADC
{
  adc_current = analogRead(ADC_1); //从A0口读取电压，模拟端口电压测量范围为0-5V，返回的值为0- 
  adc_current = (adc_current + adc_last)/2;
  if((adc_current != adc_last)&&(abs(adc_current - adc_last)>3))
  {
    adc_last = adc_current;
    int adcValue = (adc_last - 24)/10;    //24以下为关闭
    if(adcValue > 100)  adcValue = 100;
    else if(adcValue < 0) adcValue = 0;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    strip.setBrightness(adcValue);        //设置灯带总体亮度
    strip.show();
  }
}

void showModel_close()      //关闭模式
{
    for(int i = 0;i < 256;i ++)
      strip.setPixelColor(i, 0, 0, 0);
    strip.show();
}

void showModel_0()      //纯色显示，ADC调节亮度，按键二调节冷暖
{
    for(int i = 0;i < 256;i ++)
      strip.setPixelColor(i, 255, 255, 255);
    strip.show();
}

void showModel_1(int speed,bool vh)      //七彩颜色循环滚动
{
    static int offset = 0;
    offset += speed;
    if(offset > 256)    offset -= 256;
    for(int i = 0;i < 256;i ++)
    {
        int ledPos = i%16*16 + i/16;
        int pos1 = (ledPos+offset)*3;
        int pos2 = pos1 +1;
        int pos3 = pos1 +2;
        if(pos1 >= 768) pos1 -= 768;
        if(pos2 >= 768) pos2 -= 768;
        if(pos3 >= 768) pos3 -= 768;
        unsigned char r = color_model1[pos1];
        unsigned char g = color_model1[pos2];
        unsigned char b = color_model1[pos3];
        strip.setPixelColor(iToLed(i), r, g, b);
    }
    strip.show();
}

void showModel_2(int speed)   //全屏七彩切换
{
  static int colorPos = 0;
  colorPos += speed;
  if(colorPos >= 256) colorPos = 0;
  
  unsigned char r = color_model1[colorPos*3 + 0];
  unsigned char g = color_model1[colorPos*3 + 1];
  unsigned char b = color_model1[colorPos*3 + 2];
  
  for(int i = 0;i < 256;i ++)
      strip.setPixelColor(i, r, g, b);
  strip.show();
}

void showModel_3()   
{
  
}

void showModel_4()   
{
}


int iToLed(int i)
{
  if((i/16)%2)
  {
    int line = i/16;
    int led = (line + 1)*16 - i%16;
    return led;
  }
  return i; 
}

void HSVtoRGB(unsigned char *r, unsigned char *g, unsigned char *b, int h, int s, int v)
{
    int i;
    float RGB_min, RGB_max;
    RGB_max = v*2.55f;
    RGB_min = RGB_max*(100 - s)/ 100.0f;

    i = h / 60;
    int difs = h % 60; // factorial part of h
    float RGB_Adj = (RGB_max - RGB_min)*difs / 60.0f; // RGB adjustment amount by hue

    switch (i) {
    case 0:
        *r = RGB_max;
        *g = RGB_min + RGB_Adj;
        *b = RGB_min;
        break;
    case 1:
        *r = RGB_max - RGB_Adj;
        *g = RGB_max;
        *b = RGB_min;
        break;
    case 2:
        *r = RGB_min;
        *g = RGB_max;
        *b = RGB_min + RGB_Adj;
        break;
    case 3:
        *r = RGB_min;
        *g = RGB_max - RGB_Adj;
        *b = RGB_max;
        break;
    case 4:
        *r = RGB_min + RGB_Adj;
        *g = RGB_min;
        *b = RGB_max;
        break;
    default:  // case 5:
        *r = RGB_max;
        *g = RGB_min;
        *b = RGB_max - RGB_Adj;
        break;
    }
}
